package com.hxwb.robot.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hxwb.robot.dao.LoginDao;
import com.hxwb.robot.dao.RobotDao;
import com.hxwb.robot.entity.LoginEntity;
import com.hxwb.robot.entity.RobotEntity;
import com.hxwb.robot.httpEntity.PlateSortItem;
import com.hxwb.robot.request.FixedRobotReq;
import com.hxwb.robot.request.LoginReq;
import com.hxwb.robot.request.OrderReq;
import com.hxwb.robot.request.RobotReq;
import com.hxwb.robot.response.HttpRes;
import com.hxwb.robot.response.RobotRes;
import com.hxwb.robot.robotEnum.StatusEnum;
import com.hxwb.robot.util.HttpUtil;
import com.hxwb.robot.util.PathUtil;
import com.hxwb.robot.util.RandomCountUtil;
import com.hxwb.robot.util.StaticStringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
public class RobotService {
    @Autowired
    private LoginDao loginDao;
    @Autowired
    private RobotDao robotDao;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    private Logger logger = LoggerFactory.getLogger(RobotService.class);

    public void startaRobot(String symbol) {
        //登录获取token
        String token = this.getToken();
        if(token.equalsIgnoreCase("error")){
            System.out.println("token获取失败");
            return;
        }
        //机器人交易
        this.robotTrade(symbol, token);
    }


    public void startRobot(RobotEntity robotEntity) {
        redisTemplate.delete(robotEntity.getRobotNo());
        if (robotEntity.getType() == 1) {
            RobotReq robotReq = new RobotReq();
            BeanUtils.copyProperties(robotEntity, robotReq);
            try {
                this.startRandom(robotReq);
            } catch (Exception e) {
                logger.info(e.toString());
            }

        } else {
            FixedRobotReq fixedRobotReq = new FixedRobotReq();
            BeanUtils.copyProperties(robotEntity, fixedRobotReq);
            try {
                this.startFixed(fixedRobotReq);
            } catch (Exception e) {
                logger.info(e.toString());
            }

        }
    }

    public LoginEntity login(LoginReq loginReq){
        return loginDao.login(loginReq.getUsername(),loginReq.getPassword());
    }

    public RobotEntity getOne(Integer id) {
        return robotDao.getOne(id);
    }

    public RobotEntity update(RobotEntity robotEntity) {
        return robotDao.save(robotEntity);
    }

    public void delete(Integer id) {
        robotDao.deleteById(id);
    }

    private String getToken() {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("username", StaticStringUtil.username);
        paramMap.put("password", StaticStringUtil.password);
        String result = HttpUtil.post(paramMap, PathUtil.loginUrl);
        if (StringUtils.isEmpty(result) || result.equalsIgnoreCase("error")) {
            return "error";
        }
        JSONObject jsonObject = JSON.parseObject(result);
        System.out.println((int) jsonObject.get("code"));
        if ((Integer) jsonObject.get("code") != 0 || null == jsonObject.get("data")) {
            return "error";
        }
        HttpRes httpRes = JSON.toJavaObject(jsonObject, HttpRes.class);
        System.out.println("token：" + httpRes.getData().getToken());
        return httpRes.getData().getToken();
    }

    private PlateSortItem getSortItem(String symbol) {
        return HttpUtil.findTradePlate(symbol);
    }

    private BigDecimal getLastPrice(String symbol) {
        return HttpUtil.getLastPrice(symbol);
    }

    private Boolean robotTrade(String symbol, String token) {
        logger.info("机器人交易开始");
        OrderReq buyOrder = new OrderReq();
        buyOrder.setDirection("BUY");
        buyOrder.setType("LIMIT_PRICE");
        buyOrder.setSymbol(symbol);
        OrderReq sellOrder = new OrderReq();
        sellOrder.setDirection("SELL");
        sellOrder.setType("LIMIT_PRICE");
        sellOrder.setSymbol(symbol);
        Random random = new Random();
        int amountInt = random.nextInt(90) + 10;
        double point = (random.nextInt(98) + 1) * 0.01;
        BigDecimal amount = new BigDecimal(amountInt + point);
        buyOrder.setAmount(amount);
        sellOrder.setAmount(amount);

        int randomInt = random.nextInt(100) + 1;
        System.out.println("随机数：" + randomInt);
        if (randomInt % 2 == 1) {
            this.buyAfterSell(symbol, buyOrder, sellOrder, PathUtil.addOrderUrl, token);
        } else {
            this.sellAfterBuy(symbol, buyOrder, sellOrder, PathUtil.addOrderUrl, token);
        }
        return Boolean.TRUE;

    }

    public void buyAfterSell(String symbol, OrderReq buyOrder, OrderReq sellOrder, String url, String token) {
        Random random = new Random();
        PlateSortItem plateSortItem = this.getSortItem(symbol);
        if(null == plateSortItem){
            return ;
        }
        BigDecimal lastPrice = this.getLastPrice(symbol);
        if(null == lastPrice){
            return;
        }
        System.out.println("拉取价格时间：" + System.currentTimeMillis());
        System.out.println("买一卖一价格");
        System.out.println(plateSortItem);
        if (null == plateSortItem.getBuyOne() || null == plateSortItem.getSellOne() || null == lastPrice) {
            return;
        }
        BigDecimal display = plateSortItem.getSellOne().subtract(lastPrice);
        double percent = (random.nextInt(999) + 1) * 0.001;
        BigDecimal price = (display.multiply(new BigDecimal(percent)).add(lastPrice));
        buyOrder.setPrice(price);
        sellOrder.setPrice(price);
        System.out.println("时间1" + System.currentTimeMillis());
        String resultSell = HttpUtil.postAddOrder(sellOrder, url, token);
        System.out.println("时间2" + System.currentTimeMillis());
        String resultBuy = HttpUtil.postAddOrder(buyOrder, url, token);
        System.out.println("时间3" + System.currentTimeMillis());
        System.out.println(new Date() + "买单" + buyOrder);
        System.out.println(new Date() + "卖单" + sellOrder);
        System.out.println("买单结果" + resultBuy);
        System.out.println("卖单结果" + resultSell);
    }

    public void sellAfterBuy(String symbol, OrderReq buyOrder, OrderReq sellOrder, String url, String token) {
        Random random = new Random();
        PlateSortItem plateSortItem = this.getSortItem(symbol);
        if(null == plateSortItem){
            return ;
        }
        BigDecimal lastPrice = this.getLastPrice(symbol);
        if(null == lastPrice){
            return;
        }
        System.out.println("买一卖一价格");
        System.out.println(plateSortItem);
        if (null == plateSortItem.getBuyOne() || null == plateSortItem.getSellOne() || null == lastPrice) {
            return;
        }
        BigDecimal display = lastPrice.subtract(plateSortItem.getBuyOne());
        double percent = (random.nextInt(999) + 1) * 0.001;
        BigDecimal price = (display.multiply(new BigDecimal(percent)).add(plateSortItem.getBuyOne()));
        buyOrder.setPrice(price);
        sellOrder.setPrice(price);
        System.out.println("时间1" + System.currentTimeMillis());
        String resultSell = HttpUtil.postAddOrder(buyOrder, url, token);
        System.out.println("时间2" + System.currentTimeMillis());
        String resultBuy = HttpUtil.postAddOrder(sellOrder, url, token);
        System.out.println("时间3" + System.currentTimeMillis());
        System.out.println(new Date() + "买单" + buyOrder);
        System.out.println(new Date() + "卖单" + sellOrder);
        System.out.println("买单结果" + resultBuy);
        System.out.println("卖单结果" + resultSell);
    }

    public String addRobot(RobotEntity robotEntity) {
        if (null != robotDao.findByRobotNo(robotEntity.getRobotNo())) {
            return "该机器人编号已存在";
        }
        robotEntity.setStatus(1);//关闭机器人
        robotDao.save(robotEntity);
        return "添加成功";
    }

    public List<RobotRes> getRobotList() {
        List<RobotRes> robotResList = new ArrayList<>();
        List<RobotEntity> robotEntityList = robotDao.findAll();
        if (!CollectionUtils.isEmpty(robotEntityList)) {
            robotEntityList.forEach(p -> {
                RobotRes robotRes = new RobotRes();
                BeanUtils.copyProperties(p, robotRes);
                robotResList.add(robotRes);
            });
        }
        return robotResList;
    }


    private void startRandom(RobotReq startRobotReq) throws InterruptedException {
        while (true) {
            String startFlag = redisTemplate.opsForValue().get(startRobotReq.getRobotNo());
            System.out.println(startRobotReq.getRobotNo() + "随机标志位" + startFlag);
            if (StringUtils.isEmpty(startFlag)) {
                System.out.println("开始进入交易");
                redisTemplate.opsForValue().set(startRobotReq.getRobotNo(), StatusEnum.START.getStatus());
            } else if (!startFlag.equals(StatusEnum.START.getStatus())) {
                System.out.println(startRobotReq.getRobotNo() + "机器人关闭");
                break;
            }
            //确定每sumtime秒生成orderCount个订单
            List<Integer> array = RandomCountUtil.genRandList(startRobotReq.getSumTime(), startRobotReq.getOrderCount(), 8, startRobotReq.getSumTime() / 2);
            for (Integer splitTime : array) {
                this.startaRobot(startRobotReq.getSymbol());
                System.out.println(new Date() + "暂停：" + splitTime + "s");
                Thread.sleep(splitTime * 1000);
            }
        }
    }

    private void startFixed(FixedRobotReq fixedRobotReq) throws InterruptedException {
        while (true) {
            String startFlag = redisTemplate.opsForValue().get(fixedRobotReq.getRobotNo());
            if (StringUtils.isEmpty(startFlag)) {
                redisTemplate.opsForValue().set(fixedRobotReq.getRobotNo(), StatusEnum.START.getStatus());
            } else if (!startFlag.equals(StatusEnum.START.getStatus())) {
                break;
            }
            //确定每sumtime秒生成orderCount个订单
            this.startaRobot(fixedRobotReq.getSymbol());
            Thread.sleep(fixedRobotReq.getSumTime() * 1000);
        }
    }

}

